【SwiftUI】Listの背景色を変更する
SwiftUIでList
を使用すると背景色はデフォルトで薄いグレーのようなカラーになっています。デフォルトの色以外に変更したかったので調べることにしました。
環境
- Xcode 13.3
デフォルトの色
List
を表示してみました。
import SwiftUI struct ContentView: View { var body: some View { List { Text("あれ?") Text("声が") Text("遅れて") Text("聞こえてるよ") } } }
デフォルトでは、このようなグレーの色になっております。
色を変更させようとして.tint
や.background
を使用しても変更出来ませんでした。
UITableView.appearance().backgroundColorを使用する
List
の背景色を変更させるためにUITableView.appearance().backgroundColor
を使用します。
import SwiftUI struct ContentView: View { init() { UITableView.appearance().backgroundColor = .orange } var body: some View { List { Text("あれ?") Text("声が") Text("遅れて") Text("聞こえてるよ") } } }
init
メソッド時にUITableView.appearance().backgroundColor
に変更したい色を代入しています。
これでList
の背景色が変更出来ました。
Listのextensionを作成する
上記で記載した方法をextensionメソッドを作成して実施してみます。
UITableView.appearance().backgroundColor
に変更したい色を代入して、Viewを返すメソッドをList
の extensionとして作成します。今回はList
のexntensionですがForm
なども該当する為、View
のextensionでも良いかもしれません。
import SwiftUI extension List { func listBackground(_ color: Color) -> some View { UITableView.appearance().backgroundColor = UIColor(color) return self } }
Listのextensionを使用する
作成したextensionメソッドを使用する際は下記のように使用します。
import SwiftUI struct ContentView: View { var body: some View { List { Text("あれ?") Text("声が") Text("遅れて") Text("聞こえてるよ") } .listBackground(.blue) } }
同じようにList
の背景色が変更出来ました。
NavigationViewと一緒に使用してみると
NavigationView
と.listBackground(_ color:)
を一緒に使用してみました。
import SwiftUI struct ContentView: View { var body: some View { NavigationView { List { Text("あれ?") Text("声が") Text("遅れて") Text("聞こえてるよ") } .listBackground(.yellow) .navigationTitle("Title") } } }
.listBackground(_ color:)
で指定したカラーがNavigationView
の範囲まで反映されます。
UITableView.appearance()の問題点
UITableView.appearance().backgroundColor
を使うと、全てのList
の背景色が変更されます。
例として、最初に黄色のListを表示させて、NavigationBarのボタンを押すと、赤色のListに遷移してみます。
コード
ContentView(Yellow)
import SwiftUI struct ContentView: View { var body: some View { NavigationView { List { Text("あれ?") Text("声が") Text("遅れて") Text("聞こえてるよ") } .listBackground(.yellow) .navigationTitle("Yellow") .toolbar { ToolbarItem(placement: .navigationBarTrailing) { NavigationLink { NextView() } label: { Image(systemName: "chevron.right") } } } } } }
NextView(Red)
import SwiftUI struct NextView: View { var body: some View { List { Text("いいえ") Text("普通に") Text("聞こえてるよ") } .listBackground(.red) .navigationTitle("Red") } }
結果
最初にNextView
に遷移した際には、List
の色の変化は適用されますが、その色の変化が全てのList
に反映されるので前画面(ContentView)に戻った際に黄色で表示させたいはずのList
が赤色になってしまいました。
ルートビューでListの背景を透明にする方法
それぞれでUITableView.appearance().backgroundColor
を設定すると意図した状態になりませんでした。
これの対策として、まずルートビューでUITableView.appearance().backgroundColor
を透明にしておきます。
import SwiftUI @main struct KoeGaOkureteruyoApp: App { init() { UITableView.appearance().backgroundColor = .clear } var body: some Scene { WindowGroup { ContentView() } } }
backgroundにColorを指定する
.listBackground(_ color:)
のコードを削除して、.background
に置き換えます。
ContentView(Yellow)
import SwiftUI struct ContentView: View { var body: some View { NavigationView { List { Text("あれ?") Text("声が") Text("遅れて") Text("聞こえてるよ") } .background(.yellow) // .backgroundに変更 .navigationTitle("Yellow") .toolbar { ToolbarItem(placement: .navigationBarTrailing) { NavigationLink { NextView() } label: { Image(systemName: "chevron.right") } } } } } }
NextView(Red)
struct NextView: View { var body: some View { List { Text("いいえ") Text("普通に") Text("聞こえてるよ") } .background(.red) // .backgroundに変更 .navigationTitle("Red") } }
結果
それぞれのList
で意図した背景色を確認出来ました。
おわりに
appearance()
を使用すると全てのList
に影響与えてしまうことが変わり、色々と考慮しながら使う必要があることが分かりました。もし、他に良い方法等ありましたら教えていただけると嬉しいです。
いつかSwiftUIだけで容易に背景色が変更できるようになると良いね。